home *** CD-ROM | disk | FTP | other *** search
- {
- FCBIN.PAS vers 1.01 - June 1, 1988
- PUBLIC DOMAIN - JIM MURPHY - 74030,2643
-
- Program to compare two files to determine if they are different
- or identical. The difference between this and FC.EXE that comes
- with MS-DOS is; this program sends errorlevel codes that can be
- accessed within a batch file. It sends an errorlevel of zero (0)
- if the files are identical, and a one (1), if they are different.
- This program just reports what the general differences are, ie.
- Date, Length, Bytes. It also tells you the position of the first
- byte at which the files differ. You can determine where the report
- will be sent by designating an output file, but if no output file
- is designated, the report is sent to the screen. You can also
- suppress the output report by using '/s' on the command line right
- after invoking this file. An errorlevel code is always sent regard-
- less of whether the command line option '/s' is used.
-
- FCBIN |/s| <file1> <file2> |outputfile|
-
- Two filenames to compare are required, and they must be either named
- differently, or in different directories, or on different disks.
- Use lpt1 as an output file to send the report to the printer.
- }
-
-
- PROGRAM FCBIN;
-
- uses dos,crt;
-
- const
- buffmax=255; { This is the Max size, as buffers are strings }
-
- type
- results=(same,flength,fbyte,fdate);
- fnstr=string[65];
-
- var
- file1,file2:file;
- outfile:text;
- exitsave:pointer;
- iocode:word;
- result:set of results;
- stopout,fdiff:boolean;
- param1,fname1,fname2,outfn:fnstr;
- date1,date2:longint;
- length1,length2:longint;
- buffsize:word;
- buffer1,buffer2,buffert:string[buffmax];
- i:longint;
- freads,lastfread:longint;
- errorcnt:longint;
-
-
- procedure getparams;
- begin
- if paramcount<>0 then param1:=paramstr(1);
- if (paramcount<2) or (paramcount>4) or
- ((param1[1]<>'/') and (paramcount>3)) or
- ((param1[1]='/') and ((paramcount<3) or (paramcount>4)))then begin
- writeln('Incorrect parameters.');
- writeln('Correct syntax is: fcbin |/s| <file1> <file2> |outputfile|');
- writeln('/s = suppress all output');
- writeln('Errorlevel is always output:');
- writeln('0 = Files Identical');
- writeln('1 = Files different');
- writeln('A different date will not cause an errorlevel of 1 to');
- writeln('be output, but the differences will be sent to the');
- writeln('outputfile, where all differences will show.');
- writeln('If no outputfile is specified then output is to the screen.');
- halt;
- end else
- begin
- stopout:=false;
- if param1[1]<>'/' then begin
- fname1:=paramstr(1);
- fname2:=paramstr(2);
- if paramcount=3 then outfn:=paramstr(3) else outfn:='con';
- end else begin
- if (param1='/S') or (param1='/s') then stopout:=true;
- fname1:=paramstr(2);
- fname2:=paramstr(3);
- if paramcount=4 then outfn:=paramstr(4) else outfn:='con';
- end;
- if (fname1=fname2) or (fname1=outfn) or (fname2=outfn) then
- begin
- writeln('Duplicate filenames not allowed');
- halt(0);
- end;
- end;
- end; { end getparams }
-
-
- procedure prepfiles;
- begin
- assign(file1,fname1);
- assign(file2,fname2);
- if not stopout then begin
- assign(outfile,outfn);
- {$I-}
- rewrite(outfile);
- {$I+}
- iocode:=ioresult;
- if iocode<>0 then begin
- writeln('Output File Opening Error!');
- halt(iocode);
- end;
- end;
- {$I-}
- reset(file1,1);
- {$I+}
- iocode:=ioresult;
- if iocode<>0 then begin
- writeln('File #1 Opening Error!');
- halt(iocode);
- end;
- {$I-}
- reset(file2,1);
- {$I+}
- iocode:=ioresult;
- if iocode<>0 then begin
- writeln('File #2 Opening Error!');
- halt(iocode);
- end;
- end; { end prepfiles }
-
-
- procedure report;
- begin
- if same in result then exitcode:=0 else exitcode:=1;
- if not stopout then begin
- {$I-}
- writeln(outfile,'FCBIN: File #1:',fname1,' - File #2:',fname2);
- if same in result then
- writeln(outfile,'FCBIN: Files are identical')
- else writeln(outfile,'FCBIN: Files are different');
- if fdate in result then
- writeln(outfile,'FCBIN: Files dates/times are different');
- if flength in result then
- writeln(outfile,'FCBIN: Files lengths are different');
- if fbyte in result then
- writeln(outfile,'FCBIN: Files bytes are different at byte #: ',errorcnt);
- {$I+}
- iocode:=ioresult;
- close(outfile);
- if iocode<>0 then begin
- writeln('Output File Writing Error!');
- halt(iocode);
- end;
- end;
- close(file1);
- close(file2);
- halt(exitcode);
- end; { end report }
-
-
- procedure quickchek;
- begin
- result:=[same];
- getftime(file1,date1);
- getftime(file2,date2);
- if date1<>date2 then result:=result+[fdate];
- if filesize(file1)<>filesize(file2) then begin
- result:=result+[flength];
- result:=result-[same];
- fdiff:=true;
- end;
- end; { end quickchek }
-
-
- procedure errcnt;
- begin
- errorcnt:=0;
- if freads>0 then if (buffsize<>lastfread) or (lastfread=0) then
- errorcnt:=(i-1)*buffmax
- else errorcnt:=i*buffmax;
- for i:=1 to length(buffer1) do
- if buffer1[i]<>buffer2[i] then begin
- errorcnt:=errorcnt+i;
- exit;
- end;
- end; { end errcnt }
-
-
- procedure blkread;
- var
- nread1,nread2:word;
-
- begin
- {$I-}
- blockread(file1,buffer1,buffsize,nread1);
- blockread(file2,buffer2,buffsize,nread2);
- {$I+}
- iocode:=ioresult;
- if iocode=0 then begin
- buffert[1]:=buffer1[0]; { All this stuff is necessary }
- buffer1[0]:=chr(nread1); { because blockread starts }
- buffert[0]:=#1; { filling a string variable }
- buffert:=buffert+copy(buffer1,1,buffsize-1); { at position [0] in the }
- buffer1:=buffert; { string, which is supposed }
- buffert[1]:=buffer2[0]; { to contain the length byte. }
- buffer2[0]:=chr(nread2);
- buffert[0]:=#1;
- buffert:=buffert+copy(buffer2,1,buffsize-1);
- buffer2:=buffert;
- if buffer1<>buffer2 then begin
- result:=result-[same];
- result:=result+[fbyte];
- fdiff:=true;
- errcnt;
- end;
- end else begin
- writeln('File1/2 Reading Error!');
- halt(iocode);
- end;
- end; { end blkread }
-
-
- procedure compare;
- begin
- fdiff:=false;
- quickchek;
- if not fdiff then begin
- freads:=filesize(file1) div buffmax;
- lastfread:=filesize(file1) mod buffmax;
- buffsize:=sizeof(buffer1)-1;
- for i:=1 to freads do
- if not fdiff then blkread else exit;
- if lastfread<>0 then begin
- buffsize:=lastfread;
- blkread;
- end;
- end;
- end; { end compare }
-
-
- {$F+}
- procedure fcexit; {$F-}
- begin
- if exitcode>=2 then begin
- sound(1000); delay(500); nosound;
- write('Error #',iocode,' - ');
- case exitcode of
- 2:writeln('File not found.');
- 3:writeln('Path not found.');
- 4:writeln('Too many open files.');
- 5:writeln('Access denied.');
- 6:writeln('Invalid file handle.');
- 8:writeln('Insufficient memory.');
- 11:writeln('Invalid format.');
- 15:writeln('Invalid drive number.');
- 18:writeln('No more files.');
- 19:writeln('Disk is write protected.');
- 20:writeln('Bad disk unit.');
- 21:writeln('Drive not ready.');
- 23:writeln('CRC error in data.');
- 25:writeln('Disk seek error.');
- 26:writeln('Not an MS-DOS disk.');
- 27:writeln('Sector not found.');
- 28:writeln('Printer out of paper.');
- 29:writeln('Write fault.');
- 30:writeln('Read Fault.');
- 100:writeln('Disk read error.');
- 101:writeln('Disk write error.');
- 150:writeln('Disk is write protected.');
- 151:writeln('Unknown unit.');
- 152:writeln('Drive not ready.');
- 154:writeln('CRC error in data.');
- 156:writeln('Disk seek error.');
- 157:writeln('Unknown media type.');
- 158:writeln('Sector not found.');
- 159:writeln('Printer out of paper.');
- 160:writeln('Device write fault.');
- 161:writeln('Device read fault.');
- 162:writeln('Hardware failure.');
- else writeln('Unknown error.');
- end;
- end;
- exitproc:=exitsave;
- end; { end fcexit }
-
-
- BEGIN
- exitsave:=exitproc;
- exitproc:=@fcexit;
- getparams;
- prepfiles;
- compare;
- report;
- END.